﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Remoting.Contexts;
using System.Text;
using System.Windows;
using System.Windows.Navigation;

using EnvDTE;

using Microsoft.VisualStudio.TemplateWizard;
using Microsoft.Win32;

namespace Outcoder.Calcium.VSIntegration
{
	public enum CalciumProduct
	{
		Desktop,
		Phone,
		WinRT
	}

	/// <summary>
	/// This wizard provides population for the population of the replacements dictionary
	/// for Calcium module template.
	/// </summary>
	public class ModuleProjectWizard : IWizard
	{
		public void RunStarted(object automationObject, Dictionary<string, string> replacementsDictionary,
			WizardRunKind runKind, object[] customParams)
		{
			string vsVersion;
			if (!replacementsDictionary.TryGetValue("$VSVersion$", out vsVersion))
			{
				MessageBox.Show("Problem determining Visual Studio Version. Please reinstall Calcium SDK.");
				return;
			}
			if (runKind == WizardRunKind.AsNewItem)
			{
				AssignReplacements(automationObject, replacementsDictionary);
			}
			else if (runKind == WizardRunKind.AsNewProject
				|| runKind == WizardRunKind.AsMultiProject)
			{
				/* Here we derive a module name using the last part of the project name. 
				 * For example, if the user has entered MyNamespace.TextEditor 
				 * in the new project dialog, then we elect TextEditor as the module name. */
				string projectName = replacementsDictionary["$safeprojectname$"];
				string lastWord = null;
				int lastIndex = projectName.LastIndexOf('.');
				if (lastIndex != -1 && lastIndex < projectName.Length - 1)
				{
					lastWord = projectName.Substring(lastIndex + 1);
				}

				if (string.IsNullOrEmpty(lastWord))
				{
					lastWord = "Custom";
				}

				replacementsDictionary["$CustomModule$"] = lastWord;

				CalciumProduct product = ContextTool.DetermineProduct(replacementsDictionary);

				string installDir = RegistryUtil.GetCalciumInstallDirectory(product, vsVersion, "1.0");
				
				replacementsDictionary["$InstallDir$"] = installDir;

				//string[] propertyNames = new string[] { "defaultnamespace" };

				AssignReplacements(automationObject, replacementsDictionary);
			}
		}

		static void AssignReplacements(
			object automationObject, Dictionary<string, string> replacementsDictionary)
		{
			try
			{
				DTE dte = (DTE)automationObject;
				Project project = (Project)((object[])dte.ActiveSolutionProjects)[0];
				foreach (Property prop in project.Properties)
				{
					string nameLower = prop.Name.ToLower();
					if (nameLower == "defaultnamespace")
					{
						string propValue = prop.Value == null ? string.Empty : prop.Value.ToString();
						replacementsDictionary.Add("$" + nameLower + "$", propValue);
					}
				}
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.ToString());
			}
		}

		public bool ShouldAddProjectItem(string filePath)
		{
			return true;
		}

		public void RunFinished()
		{

		}

		public void BeforeOpeningFile(ProjectItem projectItem)
		{

		}

		public void ProjectItemFinishedGenerating(ProjectItem projectItem)
		{

		}

		public void ProjectFinishedGenerating(Project project)
		{

		}
	}

	public static class ContextTool
	{
		public static CalciumProduct DetermineProduct(
			Dictionary<string, string> replacementsDictionary)
		{
			const string platformKey = "Platform";
			string platform;

			if (replacementsDictionary.TryGetValue(platformKey, out platform))
			{
				switch (platform.ToLowerInvariant())
				{
					case "desktop":
						return CalciumProduct.Desktop;
					case "phone":
						return CalciumProduct.Phone;
					case "winrt":
						return CalciumProduct.WinRT;
					default:
						if (Environment.MachineName.ToLower() == "energia")
						{
							MessageBox.Show("Unknown 'Platform' value in replacements dictionary. Check the vstemplates file for the Platform variable.");
						}
						break;
				}
			}

			const string legacyKey = "Legacy";
			if (!replacementsDictionary.ContainsKey(legacyKey))
			{
				return CalciumProduct.Phone;
			}
			string parameter = replacementsDictionary["Legacy"];
			bool desktop = parameter != null && parameter.ToLower() == "true";
			CalciumProduct product = desktop ? CalciumProduct.Desktop : CalciumProduct.Phone;
			return product;
		}
	}
}
